import os
from threading import Thread
import sys
import time
import urllib3
import logging
import logging.config
import traceback
import requests
import json

from requests import Response

sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))

from conf.config import fail_max_num

from robot.dingding import DingDingRoBot
from mail.email import Mail

urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
logging.getLogger('urllib3').setLevel(logging.CRITICAL)
format = '%(asctime)s [%(threadName)s:%(thread)d] [%(name)s:%(lineno)d] [%(module)s:%(funcName)s] [%(levelname)s]- %(message)s'
formatter = logging.Formatter(format, datefmt="%Y-%m-%d %H:%M:%S")
logging.basicConfig(filename=f'./logs/detection-{time.strftime("%Y-%m-%d")}.txt', format=format, level=logging.INFO)
console = logging.StreamHandler()
console.setLevel(logging.INFO)
console.setFormatter(formatter)


class Detection(Thread):
    def __init__(self, site: dict):
        self.site_name = site["name"]
        self.site = site["config"]
        self.cookie = {}
        self.logger = logging.getLogger(__file__)
        self.logger.addHandler(console)
        self.robot = DingDingRoBot()
        self.mail = Mail()
        self.fail = {}
        super().__init__(name=self.site_name)

    def run(self) -> None:
        start_time = round(time.time())
        sleep_time = 60
        self.logger.info(f"{self.site_name} 开始监控了")
        while True:
            curr_time = round(time.time())
            if curr_time > start_time + sleep_time:
                if self.site_name != "oms小程序":
                    self.home_page()
                    if self.site_name == "chinaust_0809":
                        self.location_login()
                self.login()
                start_time = round(time.time())
            else:
                time.sleep(1)

    def home_page(self):
        try:
            res = requests.get(url=self.site["home"]["url"], verify=False)
        except:
            return self.exception_hand(self.site["home"]["url"])
        if res.status_code == 200:
            if dict(self.site["home"]).__contains__("find_word"):
                if not res.text.find(self.site["home"]["find_word"]) != -1:
                    return self.fail_hand(res)
            self.logger.info(f"{self.site_name} {sys._getframe().f_code.co_name}接口正常")
            self.fail[res.url] = 0
        else:
            self.fail_hand(res)

    def location_login(self):
        try:
            res = requests.get(url=self.site["location_login"]["url"], verify=False, allow_redirects=False)
        except:
            return self.exception_hand(self.site["home"]["url"])
        if res.status_code == 302:
            cookie = requests.utils.dict_from_cookiejar(res.cookies)
            self.cookie = cookie
            self.logger.info(f"{self.site_name} {sys._getframe().f_code.co_name}接口正常")
            self.fail[res.url] = 0
        else:
            self.fail_hand(res)

    def login(self):
        headers = {}
        if not self.site.__contains__("login"):
            return
        if self.site["login"]["content_type"] == "application/json;charset=UTF-8":
            data = json.dumps(self.site["login"]["data"])
        else:
            data = self.site["login"]["data"]
        headers["Content-Type"] = self.site["login"]["content_type"]
        try:
            res = requests.post(url=self.site["login"]["url"], headers=headers, cookies=self.cookie,
                                data=data)
        except:
            return self.exception_hand(self.site["login"]["url"])
        if res.status_code == 200:
            self.logger.info(f"{self.site_name} 登录成功")
            self.fail[res.url] = 0
        else:
            self.fail_hand(res)

    def fail_hand(self, res: Response):
        info = f"站点：{self.site_name}\n错误来源（url）：{res.url}\n请求失败反馈：{res.status_code} {res.text}"
        self.logger.info(info)
        self.judge(res.url, info)

    def exception_hand(self, url: str):
        exc_type, exc_value, exc_obj = sys.exc_info()
        exception_exc = f"站点：{self.site_name}\n错误来源（url）：{url}\n请求错误信息：{traceback.format_exc()}"
        send_exc = f"站点：{self.site_name}\n错误来源（url）：{url}\n请求错误信息：{exc_value.__repr__()}"
        self.logger.error(exception_exc)
        self.judge(url, send_exc)

    def judge(self, url: str, fail_info: str):
        if self.fail.__contains__(url):
            self.fail[url] += 1
        else:
            self.fail[url] = 1
        if self.fail[url] >= fail_max_num:
            self.fail_send(fail_info)
            self.fail[url] = 0

    def fail_send(self, fail_info: str):
        self.robot.send_message(fail_info)
        self.mail.send_mail("请求异常", fail_info)
